package com.apptude.android.trivial.gpswatch;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.location.GpsSatellite;
import android.location.GpsStatus;
import android.util.AttributeSet;
import android.view.View;

public class LocationView extends View
{
	public LocationView(Context context, AttributeSet attrs)
	{
        super(context, attrs);
	}
	
	public void gpsStatusChanged(GpsStatus gpsStatus)
	{
		myGpsStatus = gpsStatus;
		invalidate();
	}
	
	@Override
	protected void onDraw(Canvas canvas)
	{
		final int width = getWidth();
		final int height = getHeight();
		final float radius = Math.min(width, height) / 2.0f;
		final float centerX = width / 2.0f;
		final float centerY = height / 2.0f;
		
		/* paint the background this will erase the whole visible (clipped) view */
		canvas.drawColor(Color.BLACK);
		
		/* draw circles representing the elevation of the satellite 90, 60, 30 10 degrees */
		canvas.drawCircle(centerX, centerY, radius, elevationCirclePaint);
		canvas.drawCircle(centerX, centerY, (radius * 60.0f) / 90.0f, elevationCirclePaint);
		canvas.drawCircle(centerX, centerY, (radius * 30.0f) / 90.0f, elevationCirclePaint);
		canvas.drawCircle(centerX, centerY, (radius * 10.0f) / 90.0f, elevationCirclePaint);
		
		if (null != myGpsStatus)
		{
			Iterable<GpsSatellite> satellites = myGpsStatus.getSatellites();
			
			for (GpsSatellite gpsSatellite : satellites)
			{
				final float azimuth = gpsSatellite.getAzimuth();			// 0 to 360
				final float elevation = gpsSatellite.getElevation();		// 0 to 90
				float sateliteX = 0.0f;
				float sateliteY = 0.0f;
				
				if (azimuth <= 90.0f)
				{
					sateliteX = elevation * radius / 90.0f * (float)Math.sin(Math.toRadians(azimuth));
					sateliteY = elevation * radius / 90.0f * (float)Math.cos(Math.toRadians(azimuth));
				}
				else if (azimuth <= 180.0f)
				{
					sateliteX = elevation * radius / 90.0f * (float)Math.cos(Math.toRadians(azimuth - 90.0f));
					sateliteY = -(elevation * radius / 90.0f * (float)Math.sin(Math.toRadians(azimuth - 90.0f)));
				}
				else if (azimuth <= 270.0f)
				{
					sateliteX = -(elevation * radius / 90.0f * (float)Math.sin(Math.toRadians(azimuth - 180.0f)));
					sateliteY = -(elevation * radius / 90.0f * (float)Math.cos(Math.toRadians(azimuth - 180.0f)));
				}
				else if (azimuth <= 360.0f)
				{
					sateliteX = -(elevation * radius / 90.0f * (float)Math.cos(Math.toRadians(azimuth - 270.0f)));
					sateliteY = elevation * radius / 90.0f * (float)Math.sin(Math.toRadians(azimuth - 270.0f));
				}
				else
				{	
				}
				
				final Paint thisPaint = gpsSatellite.usedInFix() ?  satelliteFixCirclePaint : satelliteNoFixCirclePaint;
				canvas.drawCircle(centerX + sateliteX, centerY + sateliteY, 4.0f, thisPaint);
			}
		}
	}
	
	private GpsStatus myGpsStatus;

	final static Paint elevationCirclePaint;
	final static Paint satelliteFixCirclePaint;
	final static Paint satelliteNoFixCirclePaint;
	
	static
	{
		elevationCirclePaint = new Paint();
		elevationCirclePaint.setColor(Color.WHITE);				// background is BLACK so white is nice
		elevationCirclePaint.setStyle(Paint.Style.STROKE);		// do not fill the circle only draw the outside
		elevationCirclePaint.setAntiAlias(true);  				// Anti-Alias looks a bit better
		
		satelliteFixCirclePaint = new Paint();
		satelliteFixCirclePaint.setColor(Color.RED);					
		satelliteFixCirclePaint.setStyle(Paint.Style.FILL_AND_STROKE);		
		satelliteFixCirclePaint.setAntiAlias(true);  						// Anti-Alias looks a bit better
		
		satelliteNoFixCirclePaint = new Paint();
		satelliteNoFixCirclePaint.setColor(Color.WHITE);					
		satelliteNoFixCirclePaint.setStyle(Paint.Style.FILL_AND_STROKE);		
		satelliteNoFixCirclePaint.setAntiAlias(true);  						// Anti-Alias looks a bit better 
	}
}
